<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    function fn() {
      console.log(this)
    }

    const obj = {m: 1}
    fn() // window
    obj.fn2 = fn
    obj.fn2()  // obj
    new fn() // 新创建的fn的实例对象
    const obj2 = {m: 2}
    fn.call(obj2)  // obj2
    fn.bind(obj2)()  // obj2

    /*
    1. 常规情况: 根据函数调用的方式     
      直接调用: fn()           window/undefined
      通过对象调用: obj.fn()   obj
      new调用: new fn()       新创建的对象
      call/apply/bind调用:    obj
        fn.call/apply(obj)
        fn.bind(obj)()
    2. 特殊情况
      箭头函数: 箭头函数内部没有this, 会查找使用外部作用域的this
      回调函数  (它不是我们亲自调用的)   ==> 前提是不是使用箭头函数
        数组遍历/定时器/ajax/Promise   =>  window/undefined
        DOM事件     => 事件源标签对象
        React/Vue/小程序组件的生命周期/methods/computed => 组件对象
    扩展: 如何修改/指定函数中的this?
      call/bind
      箭头函数

      mounted () {
        // setTimeout(function (){  this是undefined
        setTimeout( () => { // 使用外部mounted中的this, 是组件对象
          this.msg = 'abc'
        }, 1000)
      }
    */
    const obj3 = {
      fn1: function () {
        console.log('fn1', this)
      },
      fn2: () => { // 箭头函数内部没有this
        console.log('fn2', this)
      }
    }
    obj3.fn1()  // obj3
    obj3.fn2()  // window

  </script>
</body>
</html>